home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / drivers / ginganin.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  14KB  |  483 lines

  1. /***************************************************************************
  2.  
  3.                             Ginga NinkyouDen
  4.                             (C) 1987 Jaleco
  5.  
  6.                     driver by Luca Elia (eliavit@unina.it)
  7.  
  8. CPU   : 68000 68B09
  9. SOUND : YM2149 Y8950(MSX AUDIO)
  10. OSC.  : 6.000MHz 3.579545MHz
  11.  
  12. * CTC uses MB-8873E (MC-6840)
  13.  
  14.                     Interesting routines (main cpu)
  15.                     -------------------------------
  16.  
  17. Interrupts:    1-7]    d17a:    clears 20018 etc.
  18.  
  19. f4b2    print string:    a1->(char)*,0x25(%)    d7.w=color    a0->screen (30000)
  20. f5d6    print 7 digit BCD number: d0.l to (a1)+ color $3000
  21.  
  22.  
  23.                     Interesting locations (main cpu)
  24.                     --------------------------------
  25.  
  26. 20014    # of players (1-2)
  27. 20018    cleared by interrupts
  28. 2001c    credits (max 9)
  29. 20020    internal timer?
  30. 20024    initial lives
  31. 20058    current lives p1
  32. 2005c    current lives p2
  33. 20070    coins
  34. 200a4    time
  35. 200a8    energy
  36.  
  37. 60008        values: 0 1 ffff
  38. 6000c        bit:    0    flip sceen?    <-    70002>>14
  39.                     1    ?            <-
  40.  
  41. 6000e    soundlatch    <- 20038 2003c 20040
  42.  
  43.  
  44.                                 To Do
  45.                                 -----
  46.  
  47. - The sound section will benefit from proper MC6840 and YM8950 emulation
  48.  
  49. ***************************************************************************/
  50.  
  51. #include "driver.h"
  52. #include "vidhrdw/generic.h"
  53. #include "cpu/m6809/m6809.h"
  54.  
  55. /* Variables only used here */
  56.  
  57. /* Variables defined in vidhrdw */
  58. extern unsigned char *ginganin_fgram, *ginganin_txtram, *ginganin_vregs;
  59.  
  60. /* Functions defined in vidhrdw */
  61. WRITE_HANDLER( ginganin_fgram_w );
  62. WRITE_HANDLER( ginganin_txtram_w );
  63. WRITE_HANDLER( ginganin_vregs_w );
  64. int  ginganin_vh_start(void);
  65. void ginganin_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
  66.  
  67.  
  68. /*
  69. **
  70. **                Main cpu data
  71. **
  72. */
  73.  
  74.  
  75. static struct MemoryReadAddress readmem[] =
  76. {
  77.     { 0x000000, 0x01ffff, MRA_ROM },
  78.     { 0x020000, 0x023fff, MRA_BANK1 },
  79.     { 0x030000, 0x0307ff, MRA_BANK2 },
  80.     { 0x040000, 0x0407ff, MRA_BANK3 },
  81.     { 0x050000, 0x0507ff, MRA_BANK4 },
  82.     { 0x060000, 0x06000f, MRA_BANK5 },
  83.     { 0x068000, 0x06bfff, MRA_BANK6 },    // bg lives in ROM
  84.     { 0x070000, 0x070001, input_port_0_r },    // controls
  85.     { 0x070002, 0x070003, input_port_1_r },    // DSWs
  86.     { -1 }
  87. };
  88.  
  89. static struct MemoryWriteAddress writemem[] =
  90. {
  91. /* The ROM area: 10000-13fff is written with: 0000 0000 0000 0001, at startup only. Why? */
  92.     { 0x020000, 0x023fff, MWA_BANK1 },
  93.     { 0x030000, 0x0307ff, ginganin_txtram_w, &ginganin_txtram },
  94.     { 0x040000, 0x0407ff, MWA_BANK3, &spriteram, &spriteram_size },
  95.     { 0x050000, 0x0507ff, paletteram_RRRRGGGGBBBBxxxx_word_w, &paletteram },
  96.     { 0x060000, 0x06000f, ginganin_vregs_w, &ginganin_vregs },
  97.     { 0x068000, 0x06bfff, ginganin_fgram_w, &ginganin_fgram },
  98.     { -1 }
  99. };
  100.  
  101.  
  102. /*
  103. **
  104. **                 Sound cpu data
  105. **
  106. */
  107.  
  108. /* based on snk.c: */
  109.  
  110. /* Added by Takahiro Nogi. 1999/09/27 */
  111. static unsigned char MC6840_index0;
  112. static unsigned char MC6840_register0;
  113. static unsigned char MC6840_index1;
  114. static unsigned char MC6840_register1;
  115. static int S_TEMPO = 0;
  116. static int S_TEMPO_OLD = 0;
  117. static int MC6809_CTR = 0;
  118. static int MC6809_FLAG = 0;
  119.  
  120.  
  121. static WRITE_HANDLER( MC6840_control_port_0_w )
  122. {
  123.     /* MC6840 Emulation by Takahiro Nogi. 1999/09/27
  124.     (This routine hasn't been completed yet.) */
  125.  
  126. //    char    mess[80];
  127.  
  128.     MC6840_index0 = data;
  129.  
  130.     if (MC6840_index0 & 0x80) {    // enable timer output
  131.         if ((MC6840_register0 != S_TEMPO) && (MC6840_register0 != 0)) {
  132.             S_TEMPO = MC6840_register0;
  133.         //    sprintf(mess, "I0:0x%02X R0:0x%02X I1:0x%02X R1:0x%02X", MC6840_index0, MC6840_register0, MC6840_index1, MC6840_register1);
  134.         //    usrintf_showmessage(mess);
  135.         }
  136.         MC6809_FLAG = 1;
  137.     } else {
  138.         MC6809_FLAG = 0;
  139.     }
  140. //    logerror("MC6840 Write:(0x%02X)0x%02X\n", MC6840_register0_index, data);
  141. }
  142.  
  143. static WRITE_HANDLER( MC6840_control_port_1_w )
  144. {
  145.     /* MC6840 Emulation by Takahiro Nogi. 1999/09/27
  146.     (This routine hasn't been completed yet.) */
  147.  
  148.     MC6840_index1 = data;
  149. }
  150.  
  151. static WRITE_HANDLER( MC6840_write_port_0_w )
  152. {
  153.     /* MC6840 Emulation by Takahiro Nogi. 1999/09/27
  154.     (This routine hasn't been completed yet.) */
  155.  
  156.     MC6840_register0 = data;
  157. }
  158.  
  159. static WRITE_HANDLER( MC6840_write_port_1_w )
  160. {
  161.     /* MC6840 Emulation by Takahiro Nogi. 1999/09/27
  162.     (This routine hasn't been completed yet.) */
  163.  
  164.     MC6840_register1 = data;
  165. }
  166.  
  167. static struct MemoryReadAddress sound_readmem[] =
  168. {
  169.     { 0x0000, 0x07ff, MRA_RAM },
  170.     { 0x1800, 0x1800, soundlatch_r },
  171.     { 0x4000, 0xffff, MRA_ROM },
  172.     { -1 }
  173. };
  174.  
  175.  
  176. static struct MemoryWriteAddress sound_writemem[] =
  177. {
  178.     { 0x0000, 0x07ff, MWA_RAM },
  179.     { 0x0800, 0x0800, MC6840_control_port_0_w },    // Takahiro Nogi. 1999/09/27
  180.     { 0x0801, 0x0801, MC6840_control_port_1_w },    // Takahiro Nogi. 1999/09/27
  181.     { 0x0802, 0x0802, MC6840_write_port_0_w },    // Takahiro Nogi. 1999/09/27
  182.     { 0x0803, 0x0803, MC6840_write_port_1_w },    // Takahiro Nogi. 1999/09/27
  183.     { 0x2000, 0x2000, Y8950_control_port_0_w },
  184.     { 0x2001, 0x2001, Y8950_write_port_0_w },
  185.     { 0x2800, 0x2800, AY8910_control_port_0_w },
  186.     { 0x2801, 0x2801, AY8910_write_port_0_w },
  187.     { -1 }
  188. };
  189.  
  190.  
  191.  
  192.  
  193. /*    Input Ports:    [0] Controls    [1] DSWs */
  194.  
  195. INPUT_PORTS_START( ginganin )
  196.  
  197.     PORT_START    // IN0 - Controls - Read from 70000.w
  198.     PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY )
  199.     PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY )
  200.     PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY )
  201.     PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY )
  202.     PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 )
  203.     PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 )
  204.     PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY | IPF_PLAYER2 )
  205.     PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY | IPF_PLAYER2 )
  206.     PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY | IPF_PLAYER2 )
  207.     PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER2 )
  208.     PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
  209.     PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER2 )
  210.     PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_COIN1 )
  211.     PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_COIN2 )
  212.     PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_START1 )
  213.     PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_START2 )
  214.  
  215.     PORT_START    // IN1 - DSWs - Read from 70002.w
  216.     PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) )
  217.     PORT_DIPSETTING(      0x0000, DEF_STR( 5C_1C ) )
  218.     PORT_DIPSETTING(      0x0004, DEF_STR( 4C_1C ) )
  219.     PORT_DIPSETTING(      0x0002, DEF_STR( 3C_1C ) )
  220.     PORT_DIPSETTING(      0x0006, DEF_STR( 2C_1C ) )
  221.     PORT_DIPSETTING(      0x0007, DEF_STR( 1C_1C ) )
  222.     PORT_DIPSETTING(      0x0003, DEF_STR( 1C_2C ) )
  223.     PORT_DIPSETTING(      0x0005, DEF_STR( 1C_3C ) )
  224.     PORT_DIPSETTING(      0x0001, DEF_STR( 1C_4C ) )
  225.     PORT_DIPNAME( 0x0038, 0x0038, DEF_STR( Coin_B ) )
  226.     PORT_DIPSETTING(      0x0000, DEF_STR( 5C_1C ) )
  227.     PORT_DIPSETTING(      0x0020, DEF_STR( 4C_1C ) )
  228.     PORT_DIPSETTING(      0x0010, DEF_STR( 3C_1C ) )
  229.     PORT_DIPSETTING(      0x0030, DEF_STR( 2C_1C ) )
  230.     PORT_DIPSETTING(      0x0038, DEF_STR( 1C_1C ) )
  231.     PORT_DIPSETTING(      0x0018, DEF_STR( 1C_2C ) )
  232.     PORT_DIPSETTING(      0x0028, DEF_STR( 1C_3C ) )
  233.     PORT_DIPSETTING(      0x0008, DEF_STR( 1C_4C ) )
  234.     PORT_BITX(    0x0040, 0x0040, IPT_DIPSWITCH_NAME | IPF_CHEAT, "Infinite Lives", IP_KEY_NONE, IP_JOY_NONE )
  235.     PORT_DIPSETTING(      0x0040, DEF_STR( Off ) )
  236.     PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
  237.     PORT_BITX(    0x0080, 0x0080, IPT_DIPSWITCH_NAME | IPF_CHEAT, "Free Play & Invulnerability", IP_KEY_NONE, IP_JOY_NONE )
  238.     PORT_DIPSETTING(      0x0080, DEF_STR( Off ) )
  239.     PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
  240.  
  241.     PORT_DIPNAME( 0x0300, 0x0300, DEF_STR( Lives ) )
  242.     PORT_DIPSETTING(      0x0000, "2")
  243.     PORT_DIPSETTING(      0x0300, "3")
  244.     PORT_DIPSETTING(      0x0100, "4")
  245.     PORT_DIPSETTING(      0x0200, "5")
  246.     PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Demo_Sounds ) )
  247.     PORT_DIPSETTING(      0x0000, DEF_STR( Off ) )
  248.     PORT_DIPSETTING(      0x0400, DEF_STR( On ) )
  249.     PORT_DIPNAME( 0x0800, 0x0000, DEF_STR( Cabinet ) )
  250.     PORT_DIPSETTING(      0x0000, DEF_STR( Upright ) )
  251.     PORT_DIPSETTING(      0x0800, DEF_STR( Cocktail ) )
  252.     PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )    // probably unused
  253.     PORT_DIPSETTING(      0x1000, DEF_STR( Off ) )
  254.     PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
  255.     PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )    // it does something
  256.     PORT_DIPSETTING(      0x2000, DEF_STR( Off ) )
  257.     PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
  258.     PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Flip_Screen ) )
  259.     PORT_DIPSETTING(      0x4000, DEF_STR( Off ) )
  260.     PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
  261.     PORT_BITX(    0x8000, 0x8000, IPT_DIPSWITCH_NAME | IPF_CHEAT, "Freeze", IP_KEY_NONE, IP_JOY_NONE )
  262.     PORT_DIPSETTING(      0x8000, DEF_STR( Off ) )
  263.     PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
  264.  
  265. INPUT_PORTS_END
  266.  
  267.  
  268.  
  269. /*
  270. **
  271. **                 Gfx data
  272. **
  273. */
  274.  
  275.  
  276. #define layout16x16(_name_,_romsize_) \
  277. static struct GfxLayout _name_ =\
  278. {\
  279.     16,16,\
  280.     (_romsize_)*8/(16*16*4),\
  281.     4,\
  282.     {0, 1, 2, 3},\
  283.     {0*4,1*4,2*4,3*4,4*4,5*4,6*4,7*4,\
  284.      0*4+32*16,1*4+32*16,2*4+32*16,3*4+32*16,4*4+32*16,5*4+32*16,6*4+32*16,7*4+32*16},\
  285.     {0*32,1*32,2*32,3*32,4*32,5*32,6*32,7*32,\
  286.      8*32,9*32,10*32,11*32,12*32,13*32,14*32,15*32},\
  287.     16*16*4\
  288. };
  289.  
  290. #define layout8x8(_name_,_romsize_) \
  291. static struct GfxLayout _name_ =\
  292. {\
  293.     8,8,\
  294.     (_romsize_)*8/(8*8*4),\
  295.     4,\
  296.     {0, 1, 2, 3},\
  297.     {0*4,1*4,2*4,3*4,4*4,5*4,6*4,7*4}, \
  298.     {0*32,1*32,2*32,3*32,4*32,5*32,6*32,7*32},\
  299.     8*8*4\
  300. };
  301.  
  302. layout16x16(tilelayout,  0x20000)
  303. layout8x8  (txtlayout,   0x04000)
  304. layout16x16(spritelayout,0x50000)
  305.  
  306. static struct GfxDecodeInfo gfxdecodeinfo[] =
  307. {
  308.     { REGION_GFX1, 0, &tilelayout,   256*3, 16 }, // [0] bg
  309.     { REGION_GFX2, 0, &tilelayout,   256*2, 16 }, // [1] fg
  310.     { REGION_GFX3, 0, &txtlayout,    256*0, 16 }, // [2] txt
  311.     { REGION_GFX4, 0, &spritelayout, 256*1, 16 }, // [3] sprites
  312.     { -1 }
  313. };
  314.  
  315.  
  316.  
  317.  
  318. int ginganin_interrupt(void)
  319. {
  320.     return 1;    /* ? (vectors 1-7 cointain the same address) */
  321. }
  322.  
  323. /* Modified by Takahiro Nogi. 1999/09/27 */
  324. int ginganin_sound_interrupt(void)
  325. {
  326.     /* MC6840 Emulation by Takahiro Nogi. 1999/09/27
  327.     (This routine hasn't been completed yet.) */
  328.  
  329.     if (S_TEMPO_OLD != S_TEMPO) {
  330.         S_TEMPO_OLD = S_TEMPO;
  331.         MC6809_CTR = 0;
  332.     }
  333.  
  334.     if (MC6809_FLAG != 0) {
  335.         if (MC6809_CTR > S_TEMPO) {
  336.             MC6809_CTR = 0;
  337.             return M6809_INT_IRQ;
  338.         } else {
  339.             MC6809_CTR++;
  340.         }
  341.     }
  342.  
  343.     return 0;
  344. }
  345.  
  346.  
  347.  
  348. static struct AY8910interface AY8910_interface =
  349. {
  350.     1,
  351.     3579545 / 2 ,    /* ? */
  352.     { 10 },
  353.     { 0 },
  354.     { 0 },
  355.     { 0 },
  356.     { 0 }
  357. };
  358.  
  359.  
  360. /* The Y8950 is basically a YM3526 with ADPCM built in */
  361. static struct Y8950interface y8950_interface =
  362. {
  363.     1,
  364.     3579545,    /* ? */
  365.     { 63 },
  366.     { 0 },
  367.     { REGION_SOUND1 },  // ROM region
  368.     { 0 },  /* keyboarc read  */
  369.     { 0 },  /* keyboard write */
  370.     { 0 },  /* I/O read  */
  371.     { 0 }   /* I/O write */
  372. };
  373.  
  374. static struct MachineDriver machine_driver_ginganin =
  375. {
  376.     {
  377.         {
  378.             CPU_M68000,
  379.             6000000,    /* ? */
  380.             readmem,writemem,0,0,
  381.             ginganin_interrupt, 1
  382.         },
  383.         {
  384.             CPU_M6809 | CPU_AUDIO_CPU,
  385.             1000000,    /* ? */        // Takahiro Nogi. 1999/09/27 (3579545 -> 1000000)
  386.             sound_readmem,sound_writemem,0,0,
  387.             ginganin_sound_interrupt, 60    // Takahiro Nogi. 1999/09/27 (1 -> 60)
  388.         },
  389.     },
  390.     60,DEFAULT_60HZ_VBLANK_DURATION,
  391.     1,
  392.     0,
  393.  
  394.     /* video hardware */
  395.     256, 256, { 0, 255, 0 + 16 , 255 - 16 },
  396.     gfxdecodeinfo,
  397.     256 * 4, 256 * 4,
  398.     0,
  399.     VIDEO_TYPE_RASTER | VIDEO_MODIFIES_PALETTE,
  400.     0,
  401.     ginganin_vh_start,
  402.     0,
  403.     ginganin_vh_screenrefresh,
  404.  
  405.     /* sound hardware */
  406.     0,0,0,0,
  407.     {
  408.         {
  409.             SOUND_AY8910,
  410.             &AY8910_interface
  411.         },
  412.         {
  413.             SOUND_Y8950,
  414.             &y8950_interface
  415.         }
  416.     }
  417. };
  418.  
  419.  
  420.  
  421. /***************************************************************************
  422.  
  423.   Game driver(s)
  424.  
  425. ***************************************************************************/
  426.  
  427. ROM_START( ginganin )
  428.     ROM_REGION( 0x20000, REGION_CPU1 )    /* main cpu */
  429.     ROM_LOAD_EVEN( "gn_02.bin", 0x00000, 0x10000, 0x4a4e012f )
  430.     ROM_LOAD_ODD(  "gn_01.bin", 0x00000, 0x10000, 0x30256fcb )
  431.  
  432.     ROM_REGION( 0x10000, REGION_CPU2 )    /* sound cpu */
  433.     ROM_LOAD( "gn_05.bin", 0x00000, 0x10000, 0xe76e10e7 )
  434.  
  435.     ROM_REGION( 0x20000, REGION_GFX1 | REGIONFLAG_DISPOSE )
  436.     ROM_LOAD( "gn_15.bin", 0x000000, 0x10000, 0x1b8ac9fb )    // bg
  437.     ROM_LOAD( "gn_14.bin", 0x010000, 0x10000, 0xe73fe668 )
  438.  
  439.     ROM_REGION( 0x20000, REGION_GFX2 | REGIONFLAG_DISPOSE )
  440.     ROM_LOAD( "gn_12.bin", 0x000000, 0x10000, 0xc134a1e9 )    // fg
  441.     ROM_LOAD( "gn_13.bin", 0x010000, 0x10000, 0x1d3bec21 )
  442.  
  443.     ROM_REGION( 0x04000, REGION_GFX3 | REGIONFLAG_DISPOSE )
  444.     ROM_LOAD( "gn_10.bin", 0x000000, 0x04000, 0xae371b2d )    // txt
  445.  
  446.     ROM_REGION( 0x50000, REGION_GFX4 | REGIONFLAG_DISPOSE )
  447.     ROM_LOAD( "gn_06.bin", 0x000000, 0x10000, 0xbdc65835 )    // sprites
  448.     ROM_CONTINUE(          0x040000, 0x10000 )
  449.     ROM_LOAD( "gn_07.bin", 0x010000, 0x10000, 0xc2b8eafe )
  450.     ROM_LOAD( "gn_08.bin", 0x020000, 0x10000, 0xf7c73c18 )
  451.     ROM_LOAD( "gn_09.bin", 0x030000, 0x10000, 0xa5e07c3b )
  452.  
  453.     ROM_REGION( 0x08000, REGION_GFX5 )    /* background tilemaps */
  454.     ROM_LOAD( "gn_11.bin", 0x00000, 0x08000, 0xf0d0e605 )
  455.  
  456.     ROM_REGION( 0x20000, REGION_SOUND1 )    /* samples */
  457.     ROM_LOAD( "gn_04.bin", 0x00000, 0x10000, 0x0ed9133b )
  458.     ROM_LOAD( "gn_03.bin", 0x10000, 0x10000, 0xf1ba222c )
  459.  
  460. ROM_END
  461.  
  462.  
  463.  
  464. void init_ginganin(void)
  465. {
  466.     unsigned char *RAM;
  467.  
  468. /* main cpu patches */
  469.     RAM = memory_region(REGION_CPU1);
  470.     WRITE_WORD(&RAM[0x408],0x6000);    WRITE_WORD(&RAM[0x40a],0x001c);    // avoid writes to rom getting to the log
  471.  
  472.  
  473. /* sound cpu patches */
  474.     RAM = memory_region(REGION_CPU2);
  475.  
  476.     /* let's clear the RAM: ROM starts at 0x4000 */
  477.     memset (&RAM[0],0,0x800);
  478.  
  479. }
  480.  
  481.  
  482. GAME( 1987, ginganin, 0, ginganin, ginganin, ginganin, ROT0, "Jaleco", "Ginga NinkyouDen" )
  483.